use std::collections::HashMap;

// 自定义 Date 结构体，并为其实现 From trait 和几个辅助函数
struct Date {
    year: u32,
    month: u32,
    day: u32,
}

impl From<String> for Date {
    fn from(value: String) -> Self {
        let component: Vec<u32> = value.split("-").map(|v| v.parse::<u32>().unwrap()).collect::<Vec<u32>>();
        assert!(component.len() == 3);
        Self { year: component[0], month: component[1], day: component[2] }
    }
}

impl Date {
    // 计算属于同一年的两个日期的距离
    // 例：self: 2024-1-1, other: 2024-1-3, 返回：2
    fn same_year_distance(&self, other: &Self) -> i32 {
        assert!(self.year == other.year);
        let days1 = self.days_to_year_end();
        let days2 = other.days_to_year_end();
        days1 - days2
    }
    // 计算到年底还有多少天
    fn days_to_year_end(&self) -> i32 {
        let mut days_per_month = vec![31,28,31,30,31,30,31,31,30,31,30,31];
        if self.year % 100 == 0 {
            if self.year % 400 == 0 {
                days_per_month[1] = 29;
            }
        } else if self.year % 4 == 0 {
            days_per_month[1] = 29;
        }

        let mut days = days_per_month[(self.month-1) as usize] - self.day as i32;
        for i in self.month ..= 11 {
            days += days_per_month[i as usize];
        }
        days
    }
}


pub fn time_info(time: &str) -> String {
    // 每年的春节日期
    let festival_time: HashMap<String, String> = serde_json::from_str(r#"{
      "2010": "2010-2-14",
      "2011": "2011-2-3",
      "2012": "2012-1-23",
      "2013": "2013-2-10",
      "2014": "2014-1-31",
      "2015": "2015-2-19",
      "2016": "2016-2-8",
      "2017": "2017-1-28",
      "2018": "2018-2-16",
      "2019": "2019-2-5",
      "2020": "2020-1-25",
      "2021": "2021-2-12",
      "2022": "2022-2-1",
      "2023": "2023-1-22",
      "2024": "2024-2-10",
      "2025": "2025-1-29",
      "2026": "2026-2-17",
      "2027": "2027-2-6",
      "2028": "2028-1-26",
      "2029": "2029-2-13",
      "2030": "2030-2-3"
    }"#).unwrap();
    
    // 每年第一个星期四的日期
    let first_thursday_time: HashMap<String, String> = serde_json::from_str(r#"{
      "2010": "2010-1-7",
      "2011": "2011-1-6",
      "2012": "2012-1-5",
      "2013": "2013-1-3",
      "2014": "2014-1-2",
      "2015": "2015-1-1",
      "2016": "2016-1-7",
      "2017": "2017-1-5",
      "2018": "2018-1-4",
      "2019": "2019-1-3",
      "2020": "2020-1-2",
      "2021": "2021-1-7",
      "2022": "2022-1-6",
      "2023": "2023-1-5",
      "2024": "2024-1-4",
      "2025": "2025-1-2",
      "2026": "2026-1-1",
      "2027": "2027-1-7",
      "2028": "2028-1-6",
      "2029": "2029-1-4",
      "2030": "2030-1-3"
    }"#).unwrap();

    let target_date = Date::from(time.to_string());

    // 距离当年第一周周一的天数
    let days_to_first_week = Date::from(first_thursday_time[&target_date.year.to_string()].clone()).same_year_distance(&target_date) + 3;
    let mut nth_week = days_to_first_week / 7 + 1;
    // target date 是星期几
    let which_day = days_to_first_week % 7;
    // 如果 target_day 距离本星期的星期四的天数还大于到年底的天数，说明本星期的星期四在下一年，本星期是下一年的第一个星期
    if 3 - which_day > target_date.days_to_year_end() {
        nth_week = 1;
    }

    // 到年底有多少天
    let days_to_year_end = target_date.days_to_year_end();

    // 计算target_date距离当年春节有多少天
    let cur_year_festival = Date::from(festival_time[&(target_date.year).to_string()].clone());
    let mut days_to_festival = target_date.same_year_distance(&cur_year_festival) - 1;

    // 如果距离是负数,说明target_date晚于当年的春节,则计算距离下一年春节有多少天
    if days_to_festival < 0 {
        // 春节距离当年 1月1日 有多少天
        let festival_shift = Date::from((target_date.year+1).to_string()+"-1-1").same_year_distance(&festival_time[&(target_date.year+1).to_string()].clone().into());
    
        // 距离春节有多少天
        days_to_festival = days_to_year_end + festival_shift;
    }

    vec![nth_week.to_string(), days_to_year_end.to_string(), days_to_festival.to_string()].join(",")
}
